/* -------------------------------------------------------------------------
 *
 * ipc.h
 *	  openGauss inter-process communication definitions.
 *
 * This file is misnamed, as it no longer has much of anything directly
 * to do with IPC.	The functionality here is concerned with managing
 * exit-time cleanup for either a postmaster or a backend.
 *
 *
 * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * src/include/storage/ipc.h
 *
 * -------------------------------------------------------------------------
 */
#ifndef IPC_H
#define IPC_H

typedef void (*pg_on_exit_callback)(int code, Datum arg);
typedef void (*shmem_startup_hook_type)(void);

extern volatile unsigned int alive_threads_waitted;

#define DEC_NUM_ALIVE_THREADS_WAITTED() alive_threads_waitted--

extern void WaitGraceThreadsExit(void);

/* ----------
 * API for handling cleanup that must occur during either ereport(ERROR)
 * or ereport(FATAL) exits from a block of code.  (Typical examples are
 * undoing transient changes to shared-memory state.)
 *
 *		PG_ENSURE_ERROR_CLEANUP(cleanup_function, arg);
 *		{
 *			... code that might throw ereport(ERROR) or ereport(FATAL) ...
 *		}
 *		PG_END_ENSURE_ERROR_CLEANUP(cleanup_function, arg);
 *
 * where the cleanup code is in a function declared per pg_on_exit_callback.
 * The Datum value "arg" can carry any information the cleanup function
 * needs.
 *
 * This construct ensures that cleanup_function() will be called during
 * either ERROR or FATAL exits.  It will not be called on successful
 * exit from the controlled code.  (If you want it to happen then too,
 * call the function yourself from just after the construct.)
 *
 * Note: the macro arguments are multiply evaluated, so avoid side-effects.
 * ----------
 */
#define PG_ENSURE_ERROR_CLEANUP(cleanup_function, arg) \
    do {                                               \
        on_shmem_exit(cleanup_function, arg);          \
    PG_TRY()

#define PG_END_ENSURE_ERROR_CLEANUP(cleanup_function, arg) \
    cancel_shmem_exit(cleanup_function, arg);              \
    PG_CATCH();                                            \
    {                                                      \
        cancel_shmem_exit(cleanup_function, arg);          \
        cleanup_function(0, arg);                          \
        PG_RE_THROW();                                     \
    }                                                      \
    PG_END_TRY();                                          \
    }                                                      \
    while (0)

struct knl_session_context;
extern void CloseClientSocket(knl_session_context* context, bool closesock);
extern void proc_exit(int code);
extern void sess_exit(int code);
extern void shmem_exit(int code);
extern void on_proc_exit(pg_on_exit_callback function, Datum arg);
extern void before_shmem_exit(pg_on_exit_callback function, Datum arg);
extern void on_shmem_exit(pg_on_exit_callback function, Datum arg);
extern void cancel_shmem_exit(pg_on_exit_callback function, Datum arg);
extern void on_exit_reset(void);

/* ipci.c */
extern void CreateSharedMemoryAndSemaphores(bool makePrivate, int port);

extern void cancelShmemExit(pg_on_exit_callback function, Datum arg);

extern void internal_delete_library();
#endif /* IPC_H */
